<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片压缩器</title>
    <style>
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 20px; background-color: #f0f2f5; color: #333; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; }
        .container { background-color: #fff; padding: 25px 30px; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.1); width: 100%; max-width: 650px; }
        h1 { text-align: center; color: #007bff; margin-bottom: 25px; font-size: 1.8em; }
        .control-group { margin-bottom: 20px; }
        label { display: block; margin-bottom: 8px; font-weight: 600; color: #555; }
        input[type="file"] { display: block; width: calc(100% - 22px); padding: 10px; border: 1px solid #ddd; border-radius: 5px; background-color: #f9f9f9; }
        #dropZone { border: 2px dashed #007bff; padding: 25px; text-align: center; border-radius: 5px; cursor: pointer; background-color: #f8f9fa; transition: background-color 0.2s ease, border-color 0.2s ease; }
        #dropZone.dragover { background-color: #e9ecef; border-color: #0056b3; }
        #dropZone p { margin: 0; color: #6c757d; }
        input[type="range"] { width: 100%; cursor: pointer; }
        .quality-info { display: flex; justify-content: space-between; font-size: 0.9em; color: #666; margin-top: 5px; }
        button {
            background-color: #007bff; color: white; padding: 12px 20px; border: none;
            border-radius: 5px; cursor: pointer; font-size: 1em; transition: background-color 0.2s ease; width: 100%;
            display: flex; align-items: center; justify-content: center;
        }
        button:hover:not(:disabled) { background-color: #0056b3; }
        button:disabled { background-color: #ccc; cursor: not-allowed; }
        .image-previews { display: flex; justify-content: space-between; gap: 20px; margin-top: 25px; }
        .preview-box { flex: 1; text-align: center; background-color: #f8f9fa; padding: 15px; border-radius: 5px; border: 1px solid #e9ecef;}
        .preview-box img { max-width: 100%; max-height: 250px; border: 1px solid #ddd; border-radius: 4px; object-fit: contain; }
        .preview-box p { font-weight: bold; margin-bottom: 8px; color: #333; }
        .info { margin-top: 8px; font-size: 0.85em; color: #555; word-wrap: break-word; }
        .download-section { margin-top: 25px; text-align: center; }
        .download-section a {
            display: inline-block; background-color: #28a745; color: white; padding: 12px 25px;
            text-decoration: none; border-radius: 5px; font-size: 1em; transition: background-color 0.2s ease;
        }
        .download-section a:hover { background-color: #218838; }
        .spinner {
            width: 20px; height: 20px; border: 3px solid rgba(255,255,255,0.3);
            border-radius: 50%; border-top-color: #fff;
            animation: spin 1s ease-in-out infinite;
            margin-right: 10px; /* Spacing between spinner and text */
        }
        .button-content { display: flex; align-items: center; justify-content: center; }
        @keyframes spin { to { transform: rotate(360deg); } }
        .message { text-align: center; padding: 10px; margin-top: 15px; border-radius: 5px; }
        .error-message { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
        .success-message { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
        #loadingIndicator { display: none; text-align: center; margin-top: 15px; color: #007bff; font-weight: bold;}

    </style>
</head>
<body>
    <div class="container">
        <h1>高级图片压缩器 🖼️</h1>

        <div class="control-group">
            <label for="fileUpload">1. 上传图片 (支持拖拽):</label>
            <div id="dropZone">
                <p>拖拽图片到这里，或点击选择文件</p>
                <input type="file" id="fileUpload" accept="image/png, image/jpeg, image/gif, image/webp" style="display: none;">
            </div>
        </div>

        <div class="image-previews">
            <div id="originalPreviewBox" class="preview-box" style="display:none;">
                <p>原始图片</p>
                <img id="imagePreview" src="#" alt="原始图片预览">
                <div id="originalFileInfo" class="info"></div>
            </div>
            <div id="compressedPreviewBox" class="preview-box" style="display:none;">
                <p>压缩后图片</p>
                <img id="compressedImagePreview" src="#" alt="压缩图片预览">
                <div id="compressedFileInfo" class="info"></div>
            </div>
        </div>

        <div class="control-group">
            <label for="qualitySlider">2. 选择压缩质量: <span id="qualityValue" style="font-weight:bold;">75</span></label>
            <input type="range" id="qualitySlider" min="1" max="100" value="75" disabled>
            <div class="quality-info">
                <span>低质量 (小文件)</span>
                <span>高质量 (大文件)</span>
            </div>
            <div class="info" style="font-size:0.8em; text-align:center; margin-top:8px;">提示: 图片通常会转为JPEG或WebP格式进行压缩。</div>
        </div>

        <button id="compressButton" disabled>
            <span class="button-content">
                <span>3. 开始压缩</span>
            </span>
        </button>
        <div id="loadingIndicator">处理中，请稍候...</div>


        <div id="messageArea"></div> <div id="downloadSection" class="download-section" style="display:none; margin-top: 20px;">
            <a id="downloadLink" href="#" download>下载压缩图片</a>
        </div>
    </div>

    <script>
        const fileUpload = document.getElementById('fileUpload');
        const dropZone = document.getElementById('dropZone');
        const imagePreview = document.getElementById('imagePreview');
        const originalPreviewBox = document.getElementById('originalPreviewBox');
        const qualitySlider = document.getElementById('qualitySlider');
        const qualityValueSpan = document.getElementById('qualityValue');
        const compressButton = document.getElementById('compressButton');
        const downloadSection = document.getElementById('downloadSection');
        const downloadLink = document.getElementById('downloadLink');
        const compressedImagePreview = document.getElementById('compressedImagePreview');
        const compressedPreviewBox = document.getElementById('compressedPreviewBox');
        const originalFileInfo = document.getElementById('originalFileInfo');
        const compressedFileInfo = document.getElementById('compressedFileInfo');
        const messageArea = document.getElementById('messageArea');
        const loadingIndicator = document.getElementById('loadingIndicator');
        const compressButtonText = compressButton.querySelector('.button-content span');


        let serverUploadedFilename = null; // 服务器上存储的文件名
        let originalClientFile = null;    // 客户端原始文件对象

        function displayMessage(text, type = 'error') {
            messageArea.innerHTML = `<div class="message ${type}-message">${text}</div>`;
        }
        function clearMessages() {
            messageArea.innerHTML = '';
        }

        function showSpinnerOnButton(show) {
            let spinner = compressButton.querySelector('.spinner');
            if (show) {
                if (!spinner) {
                    spinner = document.createElement('div');
                    spinner.className = 'spinner';
                    compressButton.querySelector('.button-content').insertBefore(spinner, compressButtonText);
                }
                compressButtonText.textContent = "压缩中...";
            } else {
                if (spinner) {
                    spinner.remove();
                }
                compressButtonText.textContent = "3. 开始压缩";
            }
        }


        // 滑块事件
        qualitySlider.addEventListener('input', (event) => {
            qualityValueSpan.textContent = event.target.value;
        });

        // 拖拽区域点击
        dropZone.addEventListener('click', () => fileUpload.click());

        // 拖拽事件
        ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
            dropZone.addEventListener(eventName, preventDefaults, false);
            document.body.addEventListener(eventName, preventDefaults, false); // Prevent browser from opening dropped file
        });
        function preventDefaults(e) {
            e.preventDefault();
            e.stopPropagation();
        }
        dropZone.addEventListener('dragenter', () => dropZone.classList.add('dragover'));
        dropZone.addEventListener('dragleave', () => dropZone.classList.remove('dragover'));
        dropZone.addEventListener('drop', handleDrop, false);

        function handleDrop(e) {
            dropZone.classList.remove('dragover');
            const dt = e.dataTransfer;
            const files = dt.files;
            if (files.length > 0) {
                if (files[0].type.startsWith('image/')) {
                    fileUpload.files = files; // 关键：将拖拽的文件赋给隐藏的input
                    handleFileSelection(files[0]);
                } else {
                    displayMessage('无效的文件类型。请上传图片文件。');
                }
            }
        }

        // 文件选择事件 (包括拖拽后手动触发)
        fileUpload.addEventListener('change', (event) => {
            if (event.target.files && event.target.files.length > 0) {
                handleFileSelection(event.target.files[0]);
            }
        });

        async function handleFileSelection(file) {
            if (!file.type.startsWith('image/')) {
                displayMessage('无效的文件类型。请上传图片文件 (PNG, JPG, GIF, WEBP)。');
                resetUIForNewUpload();
                return;
            }
            originalClientFile = file;
            clearMessages();
            loadingIndicator.style.display = 'block';
            compressButton.disabled = true;
            qualitySlider.disabled = true;
            showSpinnerOnButton(false); // Reset button text
            compressedPreviewBox.style.display = 'none';
            downloadSection.style.display = 'none';


            const reader = new FileReader();
            reader.onload = (e) => {
                imagePreview.src = e.target.result;
                originalPreviewBox.style.display = 'block';
            }
            reader.readAsDataURL(file);

            originalFileInfo.innerHTML = `名称: ${file.name}<br>大小: ${(file.size / 1024).toFixed(2)} KB<br>类型: ${file.type}`;

            const formData = new FormData();
            formData.append('file', file);

            try {
                const response = await fetch('/upload', { method: 'POST', body: formData });
                const result = await response.json();
                loadingIndicator.style.display = 'none';

                if (response.ok) {
                    serverUploadedFilename = result.filename;
                    compressButton.disabled = false;
                    qualitySlider.disabled = false;
                    displayMessage(`图片 '${result.original_client_filename}' 上传成功!`, 'success');
                } else {
                    displayMessage(`上传失败: ${result.error || '未知错误'}`);
                    resetUIForNewUpload();
                }
            } catch (error) {
                loadingIndicator.style.display = 'none';
                displayMessage(`上传错误: ${error.message}`);
                resetUIForNewUpload();
            }
        }

        function resetUIForNewUpload() {
            originalPreviewBox.style.display = 'none';
            imagePreview.src = "#";
            originalFileInfo.textContent = '';
            compressButton.disabled = true;
            qualitySlider.disabled = true;
            compressedPreviewBox.style.display = 'none';
            downloadSection.style.display = 'none';
            serverUploadedFilename = null;
            originalClientFile = null;
        }


        // 压缩按钮点击事件
        compressButton.addEventListener('click', async () => {
            if (!serverUploadedFilename || !originalClientFile) {
                displayMessage('请先上传一张图片。');
                return;
            }
            clearMessages();
            compressButton.disabled = true;
            qualitySlider.disabled = true; // Disable slider during compression
            showSpinnerOnButton(true);
            loadingIndicator.style.display = 'block';
            downloadSection.style.display = 'none';
            compressedPreviewBox.style.display = 'none';


            const quality = qualitySlider.value;

            try {
                const response = await fetch('/compress', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        filename: serverUploadedFilename,
                        original_client_filename: originalClientFile.name,
                        quality: quality
                    })
                });
                const result = await response.json();


                if (response.ok) {
                    displayMessage('图片压缩成功!', 'success');
                    downloadLink.href = result.download_url;
                    downloadLink.setAttribute('download', result.compressed_filename);

                    // 获取压缩后的图片blob用于预览和获取大小
                    const compressedImgResponse = await fetch(result.download_url);
                    if (compressedImgResponse.ok) {
                        const blob = await compressedImgResponse.blob();
                        compressedImagePreview.src = URL.createObjectURL(blob);
                        compressedFileInfo.innerHTML = `名称: ${result.compressed_filename}<br>大小: ${(blob.size / 1024).toFixed(2)} KB<br>类型: ${blob.type}`;
                        compressedPreviewBox.style.display = 'block';
                        downloadSection.style.display = 'block';
                    } else {
                        compressedFileInfo.textContent = '无法加载压缩后图片预览。';
                        compressedPreviewBox.style.display = 'block'; // Still show box, but with error
                    }
                } else {
                    displayMessage(`压缩失败: ${result.error || '未知错误'}`);
                }
            } catch (error) {
                displayMessage(`压缩时发生错误: ${error.message}`);
            } finally {
                showSpinnerOnButton(false);
                loadingIndicator.style.display = 'none';
                compressButton.disabled = false; // Re-enable button
                qualitySlider.disabled = false; // Re-enable slider
            }
        });
    </script>
</body>
</html>